//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#include "ChannelReply.h"
#include "ChannelMagic.h"

ChannelReply::ChannelReply()
{
    m_channelNumber = 0;
    m_replyPackageNumber = 0;
    m_command = 0;
    m_packageNumber = 0;
}

ChannelReply::ChannelReply(unsigned int channelNumber,
    unsigned int replyPackageNumber,
    int command):
    m_replyPackageNumber(replyPackageNumber),
    m_command(command)
{
    m_channelNumber = channelNumber;
    m_packageNumber = ChannelPackage::NextPackageNumber(); //?
}

ChannelReply::~ChannelReply()
{
}

unsigned int ChannelReply::GetPackageSize()
{
    // MagicNumber | ChannelNumber | PackageNumber | ReplyPackageNumber | CRC
    return 4 + 4 + 4 + 4 + 4;
}

void ChannelReply::WriteBuffer(char* buffer)
{
    ChannelMagic cm(m_command);
    cm.WriteBuffer(buffer);
    buffer += 4;

    WriteInteger(buffer, m_channelNumber);
    buffer += 4;

    WriteInteger(buffer, m_packageNumber);
    buffer += 4;

    WriteInteger(buffer, m_replyPackageNumber);
    buffer += 4;

    WriteInteger(buffer, CRCCheck(buffer - 12, 12));
}

int ChannelReply::Read(ReadInputStream is)
{
    int ret = ReadInteger(is, (int *)&m_channelNumber);
    if (ret != 0) {
        return CHANNEL_IO_ERROR; // io error
    }
    ret = ReadInteger(is, (int *)&m_packageNumber);
    if (ret != 0) {
        return CHANNEL_IO_ERROR; // io error
    }
    ret = ReadInteger(is, (int *)&m_replyPackageNumber);
    if (ret != 0) {
        return CHANNEL_IO_ERROR; // io error
    }
    int nCRCCheck;
    ret = ReadInteger(is, &nCRCCheck);
    if (ret != 0) {
        return CHANNEL_IO_ERROR; // io error
    }
    char buffer[12];
    WriteInteger(buffer, m_channelNumber);
    WriteInteger(buffer + 4, m_packageNumber);
    WriteInteger(buffer + 8, m_replyPackageNumber);

    if (nCRCCheck != CRCCheck((void *) buffer, 12)) {
        return CHANNEL_CRC_ERROR; // crc error
    }
    return CHANNEL_OK;
}
